package com.cloud.xtools.user.service.admin.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.xtools.common.exception.ServiceException;
import com.cloud.xtools.common.redis.RedisService;
import com.cloud.xtools.user.domain.entity.UserRole;
import com.cloud.xtools.user.mapper.UserRoleMapper;
import com.cloud.xtools.user.service.admin.RoleService;
import com.cloud.xtools.user.service.admin.UserRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author Daixinguo
 */
@Service
@RequiredArgsConstructor
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {

    @Autowired
    private RedisService redisService;

    @Override
    // 开启事务
    @Transactional
    public void assignRoles(Long userId, List<Long> roleIds) {
        // 删除该用户之前所有角色
        removeByMap(Map.of("user_id", userId));

        // 批量保存数据到 user_role 表中
        List<UserRole> userRoles = roleIds.stream()
                .map(roleId -> {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    userRole.setCreatedAt(LocalDateTime.now());
                    userRole.setUpdatedAt(LocalDateTime.now());
                    return userRole;
                })
                .toList();

        saveBatch(userRoles);

        // 将用户角色信息保存到 redis 中。保存为 set 集合
        String key = "user_role:" + userId;
        // 先删除之前分配的
        redisService.delete(key);
        roleIds.forEach(roleId -> redisService.addToSet(key, roleId));
    }

    @Override
    public void destroyByUserId(Long userId) {
        removeByMap(Map.of("user_id", userId));
    }

    @Override
    public void destroyByRoleId(Long roleId) {
        removeByMap(Map.of("role_id", roleId));
    }
}
